package com.skymxc.demo.explorer.core;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;

import com.skymxc.demo.explorer.R;
import com.skymxc.demo.explorer.util.FileUtil;
import com.skymxc.demo.explorer.util.SettingUtil;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import static com.activeandroid.Cache.getContext;

/**
 * Created by sky-mxc
 */

public class FileTask extends AsyncTask<Void ,Integer,String>{

    public static final int DELETE =1;
    public static final int CUT =2;
    public static final int COPY =3;
    public static final int COMPRESS =4;
    public static final int UNCOMPRESS =5;

    private static final int MAX = 100;
    private static final String TAG ="FileTask";

    private ProgressDialog dialog;
    private Context mContext;
    private List<File> files;
    private int action;
    private OnCompleteListener onCompleteLis;
    private int current;
    private File parentFile;

    public FileTask( Context mContext, List<File> files,int action) {
        this.mContext = mContext;
        this.files = files;
        this.action =action;
    }


    @Override
    protected void onPreExecute() {
        dialog = new ProgressDialog(mContext);
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialog.setCanceledOnTouchOutside(false);
        dialog.setMax(MAX);
        int stringRes = R.string.deleteing;
        switch (action){
            case DELETE:
                stringRes = R.string.deleteing;
                break;
            case COPY:
                stringRes = R.string.copying;
                break;
            case CUT:
                stringRes = R.string.cuting;
                break;
            case COMPRESS:
                stringRes = R.string.compressing;
                break;
            case UNCOMPRESS:
                stringRes = R.string.uncompressing;
                break;
        }
        dialog.setTitle(mContext.getString(stringRes));
        dialog.setButton(ProgressDialog.BUTTON_NEGATIVE,"取消",cancelLis);
        dialog.show();
        dialog.setProgress(0);
    }

    private DialogInterface.OnClickListener cancelLis = new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dalog, int which) {
            if (!isCancelled()) {
                cancel(true);
                dialog.setMessage(mContext.getString(R.string.canceling));
            }
        }
    };

    @Override
    protected String doInBackground(Void... params) {
        if (files==null || files.isEmpty()) return mContext.getString(R.string.unselected_file);
        switch (action){
            case DELETE:
               return delete();
            case COPY:
            case CUT:
              return  moveFile();
            case COMPRESS:
             return  compress();
            case UNCOMPRESS:
             return  uncompress();
        }
        return null;
    }

    /**
     * 解压中了
     * @return
     */
    private String uncompress() {
        String uncompressPath = SettingUtil.getUncompressPath(mContext);
        File file = files.get(0);
        String uncompressFileName = file.getName().substring(0,file.getName().lastIndexOf("."));
        File uncompressFile = new File(uncompressPath,uncompressFileName);
        if (!uncompressFile.exists()){
            uncompressFile.mkdirs();
        }

        ZipInputStream zis = null;
        long count = file.length();
        long current =0;
        try {
            zis=new ZipInputStream(new FileInputStream(file));
            ZipEntry entry;
            while ((entry=zis.getNextEntry())!=null){
                //存放时的相对路径
                String  path = entry.getName();
                File f = new File(uncompressFile,path);
                if (f.exists()){
                    f.delete();
                }

                if (entry.isDirectory()){
                    f.mkdirs();
                }else{
                    if (!f.getParentFile().exists()){
                        f.getParentFile().mkdirs();
                    }
                    if(f.createNewFile()){  //文件创建成功 ，写入内容
                        FileOutputStream fos = new FileOutputStream(f);
                        int len ;
                        byte[] b = new byte[1024];
                        while ((len=zis.read(b))!=-1){
                            Log.e(TAG,"======uncompress  len:"+len);
                            fos.write(b,0,len);
                            current+=len;
                            publishProgress((int)(((double)current)*MAX/count));
                        }
                        fos.flush();
                        fos.close();
                    }
                }

            }
            return mContext.getString(R.string.hint_uncompress);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }
        return   mContext.getString(R.string.hint_uncompress_fild);

    }



    /**
     * 压缩文件
     * @return
     */
    private String compress() {
        //读取压缩路径
        String compressPath = SettingUtil.getCompressPath(getContext());
        int count =0;
        for (File f:files){
            count+= FileUtil.getDescendantCount(f);
        }

        String compressFileName;
        if (files.size()==1){
            File file = files.get(0);
            FileType type = FileType.parseFile(file);
            if(type == FileType.DIR || type == FileType.UNKNOW){
                compressFileName = file.getName();
            }else{
                String fileName = file.getName();
                compressFileName=fileName.substring(0,fileName.lastIndexOf("."));
            }
        }else{
            compressFileName = files.get(0).getParentFile().getName();
        }

        try {
            File compressFile = new File(compressPath,compressFileName+".zip");
            if (compressFile.exists()) {
                compressFile.delete();
            }else{
                if (!compressFile.getParentFile().exists()){
                    compressFile.getParentFile().mkdirs();
                }
            }
            if (compressFile.createNewFile()) {
                ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(compressFile));
                for (File f : files) {
                    compress(zos, f, "", count);
                }

                zos.flush();
                zos.close();
                return String.format(mContext.getString(R.string.hint_comress), count, current);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }




        return  mContext.getString(R.string.hint_comress_fild);
    }

    /**
     * 进行文件压缩
     * @param zos
     * @param file
     * @param rpPath 相对父级的路径
     */
    private void compress(ZipOutputStream zos, File file, String rpPath,int count) {
        publishProgress(++current*MAX/count);
        try {
            if (file.isFile()){
                ZipEntry entry = new ZipEntry(rpPath+file.getName());
                zos.putNextEntry(entry);
                FileInputStream fis = new FileInputStream(file);
                int len = -1;
                byte[] b = new byte[1024];
                while ((len=fis.read(b))!=-1){
                    zos.write(b,0,len);
                }
                fis.close();
            }else{
                File[] files = file.listFiles();
                String path = rpPath+file.getName()+File.separator;
                if (file.length() ==0){
                    //File.separator 必须加 这是区分 文件和文件夹的标识
                    ZipEntry entry = new ZipEntry(path);
                    zos.putNextEntry(entry);

                    return;
                }
                for (File f:files){
                    compress(zos,f,path,count);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /** ===actionMode:
     *
     * @return
     */
    private String moveFile() {
        int count =0;
        for (File f:files){
            count+= FileUtil.getDescendantCount(f);
        }
        for (File f:files){
            move(f,parentFile,count);
        }
        int res = action==CUT?R.string.hint_cut:R.string.hint_copy;
        return   String.format(mContext.getString(res),count,current);
    }

    /**
     * 移动
     * @param file 移动的文件
     * @param count 总数量
     * @param parentFile 要移到的文件夹
     */
    private void move(File file,File parentFile, int count) {
        String fileName = file.getName();
        File moveFile = new File(parentFile,fileName);
        if (moveFile.exists()){
            moveFile.delete();
        }
        if (file.isFile()){
          if(FileUtil.copyFile(file,moveFile)){
              publishProgress(++current*MAX/count);
              if (action==CUT){
                  //源文件删除
                  file.delete();
              }
          }
        }else{
            moveFile.mkdir();
            publishProgress(++current*MAX/count);
            File[] files = file.listFiles();
            if (file.length() > 0){
                for (File f :files){
                  move(f,moveFile,count);
                }
            }
            if (action==CUT){
                //源文件删除
                file.delete();
            }
        }


    }

    @Override
    protected void onCancelled(String s) {
        onPostExecute(s);
    }

    /**
     * 删除
     * @return
     */
    private String delete() {
        int count =0;
        for (File f:files){
          count+= FileUtil.getDescendantCount(f);
        }
        Log.v(TAG,"==删除count："+count);
        for (File f:files){
            delete(f,count);
        }
        return  String.format(mContext.getString(R.string.hint_delete),count,current);
    }

    /**
     * 删除文件（包含子文件）
     * @param file
     * @return
     */
    private void  delete(File file,int count){
        Log.v(TAG,"删除："+ file.getName());
        if (file.isFile()){
           if(file.delete()) {
               publishProgress(++current * MAX / count);
           }
        }else{
            for (File f :file.listFiles()){
             delete(f,count);
            }
            if(file.delete()) {
                publishProgress(++current * MAX / count);
            }
        }
    }



    @Override
    protected void onProgressUpdate(Integer... values) {
        //Log.e(TAG,"===progress:"+values[0]);
       dialog.setProgress(values[0]);
    }

    @Override
    protected void onPostExecute(String s) {
        if (onCompleteLis!=null)
            onCompleteLis.onComplete();
        if (dialog!=null && dialog.isShowing()){
            dialog.cancel();
            dialog=null;
        }
        Toast.makeText(mContext,s,Toast.LENGTH_SHORT).show();
    }

    public void setOnCompleteLis(OnCompleteListener onCompleteLis) {
        this.onCompleteLis = onCompleteLis;
    }

    public void setParentFile(File parentFile) {
        this.parentFile = parentFile;
    }

    //完成时的监听
    public interface  OnCompleteListener{
        void onComplete();
    }
}
